package com.gaoch.simweather.logic

import androidx.lifecycle.liveData
import com.gaoch.simweather.logic.dao.PlaceDao
import com.gaoch.simweather.logic.model.PlaceResponse
import com.gaoch.simweather.logic.model.Weather
import com.gaoch.simweather.logic.network.SimWeatherNetwork
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import java.lang.Exception
import java.lang.RuntimeException
import kotlin.coroutines.CoroutineContext

object Repository {
    private fun <T> fire(context:CoroutineContext,block:suspend()->Result<T>)=liveData<Result<T>>(context){
        val result=try{
            block()
        }catch (e:Exception){
            Result.failure<T>(e)
        }
        emit(result)
    }

    /**以下方法每次需要使用try-catch处理，较为繁琐**/
    /**
    fun searchPlaces(query:String)= liveData(Dispatchers.IO) {
        val result=try {
            val placeResponse=SimWeatherNetwork.searchPlaces(query)
            if(placeResponse.status=="200"){
                val places=placeResponse.location
                Result.success(places)
            }else{
                Result.failure(RuntimeException("response status is ${placeResponse.status}"))
            }
        }catch (e:Exception){
            Result.failure<List<Location>>(e)
        }
        emit(result)
    }
    **/

    /**查询城市**/
    fun searchPlaces(query:String)= fire(Dispatchers.IO) {
        val placeResponse=SimWeatherNetwork.searchPlaces(query)
        if(placeResponse.status=="200"){
            val places=placeResponse.location
            Result.success(places)
        }else{
            Result.failure(RuntimeException("response status is ${placeResponse.status}"))
        }
    }
    /**根据城市 获取天气信息**/
    fun getWeather(location:String)= fire(Dispatchers.IO) {
        coroutineScope {
            val defferedNow=async{
                SimWeatherNetwork.getNowWeather(location)
            }
            val defferedDaily=async {
                SimWeatherNetwork.getDailyWeather(location)
            }
            val defferedAqi=async {
                SimWeatherNetwork.getAqi(location)
            }
            val defferedHourly=async {
                SimWeatherNetwork.getHourlyWeather(location)
            }
            val nowWeather=defferedNow.await()
            val dailyWeather=defferedDaily.await()
            val aqi=defferedAqi.await()
            val hourly=defferedHourly.await()

            if(nowWeather.code=="200"&&dailyWeather.code=="200"&&aqi.code=="200"&&hourly.code=="200"){
                val weather=Weather(nowWeather.now,dailyWeather.daily,aqi.now,hourly.hourly)
                Result.success(weather)
            }else{
                Result.failure(RuntimeException("NowResponse status is ${nowWeather.code},DailyResponse status is ${dailyWeather.code}"))
            }

        }
    }

    fun savePlace(place:PlaceResponse.Location)=PlaceDao.savePlace(place)

    fun getSavePlace()=PlaceDao.getSavedPlace()

    fun isPlaceSaved()=PlaceDao.isPlaceSaved()

}